\chapter{Message Framing}

Comme l'impose le sujet, nous ne pouvions pas utiliser de caractère de terminaison de chaque message. Bien que ce fonctionnement soit tout à fait possible malgré la présence d'informations binaires dans les messages dans la mesure où toutes les parties de messages binaires ont une longueur fixe connue (les parties en binaire sont le buffermap et les pièces). \\

Il fallait donc lire les messages par petits bouts, jusqu'à reconnaître un message entier. Dans chacun des programmes (pair et tracker), la lecture des messages s'effectue de la manière suivante : \\

\begin{enumerate}
\item On lit $x$ octets depuis la socket réseau
\item On les concatène à un buffer de lecture de message $buffer$
\item On essaie de parser $buffer$ afin de savoir si le message qu'il contient est correct. :
\begin{itemize}
\item S'il ne l'est pas mais que le premier mot (la commande) est connue, on remonte en 1) pour poursuivre la lecture ;
\item S'il ne l'est pas et que le premier mot (la commande) n'est pas connue, on vide le buffer et on ignore le message silencieusement ;
\item S'il l'est on le prend en compte et on vide le buffer pour préparer la réception d'un nouveau message \\
\end{itemize}
\end{enumerate}

La figure \ref{bufferlecture} illustre le remplissage pas à pas du buffer. \\

\begin{center} 
\begin{figure}[!h]
   \caption{\label{bufferlecture} Remplissage du buffer de message}
   \includegraphics[width=10cm]{bufferlecture.png}
\end{figure}
\end{center} 

Lorsque l'on parse le $buffer$ pour déterminer si la commande est correcte, nous comparons chaque mot avec celui ou ceux attendus, puis en lisant ensuite tous les caractères jusqu'au caractère "espace" suivant, à l'exception des morceaux binaires. Pour ces derniers nous savons à quel instant ils commençent et nous connaissons directement leur longueur, il suffit donc d'effectuer la lecture au bon moment sur la bonne longueur. \\

Ajoutons que les expressions régulières étaient particulièrement adaptées pour la lecture des messages textes. Nous aurions donc pû les utiliser. \\

Nous avons choisi $x$ comme étant égal à la longueur du plus petit message du protocole. Ce choix permet d'éviter d'être obligé d'attendre l'arrivée d'un autre message pour que le petit message soit pris en compte. Dans notre protocole $x=2$ car le plus petit message est $ok$. Cette valeur n'est pas très optimale car elle oblige de nombreuses lectures, ce qui est particulièrement coûteux lors de la lecture de gros messages contenant des pièces par exemple. \\

Note : le pair dispose de deux macros READ et READ\_DATA, qui sont l'équivalent d'une lecture bufferisée et qui lisent respectivement un mot de longueur inconnue et un mot de taille définie. READ est utilisé pour les lectures des mots-clés des messages, il lit jusqu'au prochain espace. READ\_DATA est utilisé pour la lecture des données binaires, il lit le nombre d'octets demandé en paramètre. Le tracker étant écrit en Java des fonctions font cela déjà à notre place, par exemple $String.split()$ qui découpe une chaîne en un tableau et permet donc d'obtenir chaque mot indépendemment.
